package com.liangzhong.message.http
{
	import com.common.utils.TimeFrameUtil;
	import com.liangzhong.constants.NotificationConstants;
	import com.liangzhong.events.AppEventDispatcher;
	
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;

	/**
	 * http 短连接 封装
	 * @author lake
	 */	
	public class WebClient
	{
		/**
		 *加载器 
		 */		
		protected var loader		:URLLoader;
		/**
		 *请求 
		 */		
		protected var request      	:URLRequest;
		/**
		 *提交方法 post --- get 
		 */		
		private var _method		:String;
		/**
		 *请求地址 
		 */		
		private var _svrUrl		:String;
		/**
		 *回调 
		 */		
		protected var callBack		:Function;
		/**
		 *错误回调 
		 */		
		protected var errCallBack	:Function;
		/**
		 *请求头类型 
		 */		
		private var _contentType	:String;
		/**
		 *编码 
		 */		
		private var _charset		:String;
		/**
		 *结果数据返回格式 
		 */		
		private var _resultFormat	:String;
		/**
		 * 超时 毫秒数
		 */		
		private var _timeOut		:int = 5000;
		/**
		 *超时重复请求次数 
		 */		
		private var _repeatTimes   :int = 3;
		/**
		 *当前请求经过的时间 
		 */		
		private var requestTotalTime :int;
		/**
		 *当前请求次数 
		 */		
		private var curRequestTime	  :int = 1;
		/**
		 *是否需要等待数据回来再操作
		 */		
		private var _isAddReqWaiting	:Boolean = true;
		
		public function WebClient()
		{
			_charset			= "utf-8"; //默认编码utf-8
			loader				= new URLLoader();
			loader.dataFormat	= URLLoaderDataFormat.BINARY;
			_method				= "POST";    //默认请求方式POST
			_contentType		= "application/x-www-form-urlencoded";
			// 提供两种结果类型，默认文本。如果为binary,则不存在编码转换之分
			_resultFormat		= "text";  //"binary"
			//event listener
			loader.addEventListener(Event.COMPLETE,dataLoaded);
			loader.addEventListener(IOErrorEvent.IO_ERROR,loadError);
		}
		/**
		 * loadComplete 数据返回
		 * @param e
		 * 
		 */		
		protected function dataLoaded(e:Event):void
		{
			TimeFrameUtil.instance.removeMethod(timing);
			// delete mark sp
			if(isAddReqWaiting)
			{
				isAddReqWaiting = false;
				AppEventDispatcher.getInstance().dispatchEvent(new Event(NotificationConstants.Application_Un_Show_Req_Mark));
			}
			if(callBack!=null)
			{
				if(_resultFormat=="text")
				{
					var buf:ByteArray=loader.data as ByteArray;
					callBack(buf.readMultiByte(buf.length,_charset));
				}
				else
				{
					callBack(loader.data);
				}
				callBack=null;
			}
			//destroy
			destroy();
		}
		/**
		 * load 错误
		 * @param e
		 * 
		 */		
		protected function loadError(e:IOErrorEvent):void
		{
			TimeFrameUtil.instance.removeMethod(timing);
			trace(e);
			if(errCallBack != null)
			{
				errCallBack(e);
				errCallBack = null;
			}
			// delete mark sp
			if(isAddReqWaiting)
			{
				isAddReqWaiting = false;
				AppEventDispatcher.getInstance().dispatchEvent(new Event(NotificationConstants.Application_Un_Show_Req_Mark));
			}
			//destroy
			destroy();
		}
		/**
		 * 设置结果格式
		 * @param value
		 * 
		 */		
		public function set resultFormat(value:String):void
		{
			_resultFormat = value;
		}
		/**
		 * 返回结果格式
		 * @return 
		 * 
		 */		
		public function get resultFormat():String
		{
			return _resultFormat;
		}
		/**
		 * 设置编码 默认utf-8
		 * @param value
		 * 
		 */		
		public function set charset(value:String):void
		{
			_charset = value;
		}
		/**
		 * 返回编码
		 * @return 
		 * 
		 */		
		public function get charset():String
		{
			return _charset;
		}
		/**
		 * 设置访问设置  post/ get
		 * @param m
		 * 
		 */		
		public function set method(m:String):void
		{
			_method = m;
		}
		/**
		 * 返回方法
		 * @return 
		 * 
		 */		
		public function get method():String
		{
			return _method;
		}
		/**
		 * 设置server 地址
		 * @param url
		 * 
		 */		
		public function set svrUrl(url:String):void
		{
			_svrUrl = url;
		}
		/**
		 * 获取请求地址
		 * @return 
		 * 
		 */		
		public function get svrUrl():String
		{
			return _svrUrl;
		}
		/**
		 * setHeader
		 * @param header
		 * @param value
		 * 
		 */		
		public function setHeader(header:String, value:String):void
		{
		}
		/**
		 * get contentType
		 * @return 
		 * 
		 */		
		public function get contentType():String
		{
			return _contentType;
		}
		/**
		 * set contentType
		 * @param ct
		 * 
		 */		
		public function set contentType(ct:String):void
		{
			_contentType = ct;
		}
		/**
		 *设置超时
		 * @param value
		 * 
		 */		
		public function set timeOut(value :int):void
		{
			_timeOut = value;
		}
		/**
		 * 返回超时
		 * @return 
		 * 
		 */		
		public function get timeOut():int
		{
			return _timeOut;
		}
		/**
		 * 设置超时请求次数
		 * @param value
		 * 
		 */		
		public function set repeatTimes(value :int):void
		{
			_repeatTimes = value;
		}
		/**
		 * 获取超时请求次数
		 * @return 
		 * 
		 */		
		public function get repeatTimes():int
		{
			return _repeatTimes;
		}
		/**
		 * 设置是否需要添加蒙板限制操作
		 * @param value
		 * 
		 */		
		public function set isAddReqWaiting(value :Boolean):void
		{
			_isAddReqWaiting = value;
		}
		/**
		 * 获取是否需要添加蒙板限制操作
		 * @return 
		 * 
		 */		
		public function get isAddReqWaiting():Boolean
		{
			return _isAddReqWaiting;
		}
		/**
		 * call http server
		 * @param callback
		 * @param arg
		 * @param errCallback
		 * 
		 */		
		public function call(callback:Function, 
							 arg:Object = null,
							 errCallback:Function = null):void
		{
			callBack	= callback;
			errCallBack	= errCallback;
			
			request				= new URLRequest(_svrUrl);
			request.method		= _method;
			request.contentType	= _contentType;
			request.data		= arg;
			loader.load(request);
			//trace("Request Method:",arg.method);
			//add mark
			if(isAddReqWaiting)
			{
				AppEventDispatcher.getInstance().dispatchEvent(new Event(NotificationConstants.Application_Show_Req_Mark));
			}
			//listener time out
			TimeFrameUtil.instance.addMethod(timing);
		}
		/**
		 *计算时间 
		 * @param passT
		 * 
		 */		
		private function timing(passT :int):void
		{
			requestTotalTime += passT;
			if(requestTotalTime >= timeOut)//请求超时
			{
				//trace(request.url,request.data,request.data.method);
				requestTotalTime = 0;
				loader.close();
				loader.load(request);
				curRequestTime ++ ;
			}
			if(curRequestTime >= repeatTimes)//请求次数超过
			{
				TimeFrameUtil.instance.removeMethod(timing);
				// delete mark sp
				if(isAddReqWaiting)
				{
					isAddReqWaiting = false;
					AppEventDispatcher.getInstance().dispatchEvent(new Event(NotificationConstants.Application_Un_Show_Req_Mark));
				}
			}
		}
		/**
		 *数据正常返回 后 销毁 
		 * 
		 */		
		protected function destroy():void
		{
			loader.removeEventListener(Event.COMPLETE,dataLoaded);
			loader.removeEventListener(IOErrorEvent.IO_ERROR,loadError);
			loader = null;
			request = null;
			callBack = null;
			errCallBack = null;
		}
	}

}